// ==================== IndexedDB存储服务 ====================
// 基础设施层存储模块
// 职责：提供IndexedDB本地存储能力，实现数据持久化

/**
 * IndexedDB存储服务类
 * 负责管理IndexedDB数据库，提供数据持久化能力
 */
export class IndexedDBStorage {
  /**
   * 构造函数
   * @param {string} dbName - 数据库名称
   * @param {number} version - 数据库版本
   */
  constructor(dbName = 'DesignAppDB', version = 1) {
    // ==================== 核心属性 ====================
    this.dbName = dbName
    this.version = version
    this.db = null
    this.isInitialized = false
    
    // ==================== 存储配置 ====================
    this.stores = {
      projects: 'projects',           // 项目存储
      elements: 'elements',           // 元素存储
      settings: 'settings',           // 设置存储
      templates: 'templates',         // 模板存储
      assets: 'assets'                // 资源存储
    }
    
    // ==================== 索引配置 ====================
    this.indexes = {
      projects: {
        name: 'name',                 // 项目名称索引
        createdAt: 'createdAt',       // 创建时间索引
        updatedAt: 'updatedAt'        // 更新时间索引
      },
      elements: {
        projectId: 'projectId',       // 项目ID索引
        type: 'type',                 // 元素类型索引
        layerId: 'layerId'            // 图层ID索引
      }
    }
    
    // ==================== 性能监控 ====================
    this.performance = {
      readCount: 0,                   // 读取次数
      writeCount: 0,                  // 写入次数
      deleteCount: 0,                 // 删除次数
      totalSize: 0                    // 总数据大小
    }
  }
  
  /**
   * 初始化数据库
   * 创建数据库和对象存储
   */
  async initialize() {
    try {
      // 检查IndexedDB支持
      if (!window.indexedDB) {
        throw new Error('浏览器不支持IndexedDB')
      }
      
      // 打开数据库
      const request = indexedDB.open(this.dbName, this.version)
      
      // 数据库升级事件
      request.onupgradeneeded = (event) => {
        this.createStores(event.target.result)
      }
      
      // 数据库打开成功
      request.onsuccess = (event) => {
        this.db = event.target.result
        this.isInitialized = true
        console.log('IndexedDB数据库初始化成功')
      }
      
      // 数据库打开失败
      request.onerror = (event) => {
        throw new Error(`数据库打开失败: ${event.target.error}`)
      }
      
      // 等待数据库初始化完成
      return new Promise((resolve, reject) => {
        request.onsuccess = (event) => {
          this.db = event.target.result
          this.isInitialized = true
          console.log('IndexedDB数据库初始化成功')
          resolve()
        }
        
        request.onerror = (event) => {
          reject(new Error(`数据库打开失败: ${event.target.error}`))
        }
      })
      
    } catch (error) {
      console.error('IndexedDB初始化失败:', error)
      throw error
    }
  }
  
  /**
   * 创建对象存储
   * @param {IDBDatabase} db - 数据库实例
   */
  createStores(db) {
    // 创建项目存储
    if (!db.objectStoreNames.contains(this.stores.projects)) {
      const projectStore = db.createObjectStore(this.stores.projects, { keyPath: 'id' })
      
      // 创建索引
      projectStore.createIndex(this.indexes.projects.name, 'name', { unique: false })
      projectStore.createIndex(this.indexes.projects.createdAt, 'createdAt', { unique: false })
      projectStore.createIndex(this.indexes.projects.updatedAt, 'updatedAt', { unique: false })
    }
    
    // 创建元素存储
    if (!db.objectStoreNames.contains(this.stores.elements)) {
      const elementStore = db.createObjectStore(this.stores.elements, { keyPath: 'id' })
      
      // 创建索引
      elementStore.createIndex(this.indexes.elements.projectId, 'projectId', { unique: false })
      elementStore.createIndex(this.indexes.elements.type, 'type', { unique: false })
      elementStore.createIndex(this.indexes.elements.layerId, 'layerId', { unique: false })
    }
    
    // 创建设置存储
    if (!db.objectStoreNames.contains(this.stores.settings)) {
      db.createObjectStore(this.stores.settings, { keyPath: 'key' })
    }
    
    // 创建模板存储
    if (!db.objectStoreNames.contains(this.stores.templates)) {
      const templateStore = db.createObjectStore(this.stores.templates, { keyPath: 'id' })
      templateStore.createIndex('category', 'category', { unique: false })
    }
    
    // 创建资源存储
    if (!db.objectStoreNames.contains(this.stores.assets)) {
      const assetStore = db.createObjectStore(this.stores.assets, { keyPath: 'id' })
      assetStore.createIndex('type', 'type', { unique: false })
      assetStore.createIndex('category', 'category', { unique: false })
    }
  }
  
  /**
   * 保存数据
   * @param {string} storeName - 存储名称
   * @param {Object} data - 要保存的数据
   * @returns {Promise<string>} 保存的数据ID
   */
  async save(storeName, data) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite')
      const store = transaction.objectStore(storeName)
      
      // 添加时间戳
      const dataWithTimestamp = {
        ...data,
        updatedAt: new Date().toISOString()
      }
      
      if (!dataWithTimestamp.createdAt) {
        dataWithTimestamp.createdAt = new Date().toISOString()
      }
      
      const request = store.put(dataWithTimestamp)
      
      request.onsuccess = () => {
        this.performance.writeCount++
        resolve(request.result)
      }
      
      request.onerror = () => {
        reject(new Error(`保存数据失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 获取数据
   * @param {string} storeName - 存储名称
   * @param {string} id - 数据ID
   * @returns {Promise<Object>} 获取的数据
   */
  async get(storeName, id) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly')
      const store = transaction.objectStore(storeName)
      const request = store.get(id)
      
      request.onsuccess = () => {
        this.performance.readCount++
        resolve(request.result)
      }
      
      request.onerror = () => {
        reject(new Error(`获取数据失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 获取所有数据
   * @param {string} storeName - 存储名称
   * @returns {Promise<Array>} 所有数据
   */
  async getAll(storeName) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly')
      const store = transaction.objectStore(storeName)
      const request = store.getAll()
      
      request.onsuccess = () => {
        this.performance.readCount++
        resolve(request.result)
      }
      
      request.onerror = () => {
        reject(new Error(`获取所有数据失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 根据索引查询数据
   * @param {string} storeName - 存储名称
   * @param {string} indexName - 索引名称
   * @param {*} value - 查询值
   * @returns {Promise<Array>} 查询结果
   */
  async getByIndex(storeName, indexName, value) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly')
      const store = transaction.objectStore(storeName)
      const index = store.index(indexName)
      const request = index.getAll(value)
      
      request.onsuccess = () => {
        this.performance.readCount++
        resolve(request.result)
      }
      
      request.onerror = () => {
        reject(new Error(`索引查询失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 删除数据
   * @param {string} storeName - 存储名称
   * @param {string} id - 数据ID
   * @returns {Promise<void>}
   */
  async delete(storeName, id) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite')
      const store = transaction.objectStore(storeName)
      const request = store.delete(id)
      
      request.onsuccess = () => {
        this.performance.deleteCount++
        resolve()
      }
      
      request.onerror = () => {
        reject(new Error(`删除数据失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 清空存储
   * @param {string} storeName - 存储名称
   * @returns {Promise<void>}
   */
  async clear(storeName) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readwrite')
      const store = transaction.objectStore(storeName)
      const request = store.clear()
      
      request.onsuccess = () => {
        resolve()
      }
      
      request.onerror = () => {
        reject(new Error(`清空存储失败: ${request.error}`))
      }
    })
  }
  
  /**
   * 获取存储统计信息
   * @param {string} storeName - 存储名称
   * @returns {Promise<Object>} 统计信息
   */
  async getStoreStats(storeName) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([storeName], 'readonly')
      const store = transaction.objectStore(storeName)
      const countRequest = store.count()
      
      countRequest.onsuccess = () => {
        resolve({
          count: countRequest.result,
          storeName: storeName
        })
      }
      
      countRequest.onerror = () => {
        reject(new Error(`获取统计信息失败: ${countRequest.error}`))
      }
    })
  }
  
  /**
   * 获取数据库统计信息
   * @returns {Promise<Object>} 数据库统计信息
   */
  async getDatabaseStats() {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    const stats = {
      dbName: this.dbName,
      version: this.version,
      stores: {},
      performance: { ...this.performance }
    }
    
    // 获取每个存储的统计信息
    for (const storeName of Object.values(this.stores)) {
      try {
        const storeStats = await this.getStoreStats(storeName)
        stats.stores[storeName] = storeStats
      } catch (error) {
        console.warn(`获取存储 ${storeName} 统计信息失败:`, error)
      }
    }
    
    return stats
  }
  
  /**
   * 备份数据库
   * @returns {Promise<Object>} 备份数据
   */
  async backup() {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    const backup = {
      timestamp: new Date().toISOString(),
      dbName: this.dbName,
      version: this.version,
      data: {}
    }
    
    // 备份每个存储的数据
    for (const storeName of Object.values(this.stores)) {
      try {
        backup.data[storeName] = await this.getAll(storeName)
      } catch (error) {
        console.warn(`备份存储 ${storeName} 失败:`, error)
        backup.data[storeName] = []
      }
    }
    
    return backup
  }
  
  /**
   * 恢复数据库
   * @param {Object} backup - 备份数据
   * @returns {Promise<void>}
   */
  async restore(backup) {
    if (!this.isInitialized) {
      throw new Error('数据库未初始化')
    }
    
    // 验证备份数据
    if (!backup.data || typeof backup.data !== 'object') {
      throw new Error('无效的备份数据')
    }
    
    // 恢复每个存储的数据
    for (const [storeName, data] of Object.entries(backup.data)) {
      if (Array.isArray(data)) {
        // 清空现有数据
        await this.clear(storeName)
        
        // 恢复数据
        for (const item of data) {
          await this.save(storeName, item)
        }
      }
    }
    
    console.log('数据库恢复完成')
  }
  
  /**
   * 关闭数据库连接
   */
  close() {
    if (this.db) {
      this.db.close()
      this.db = null
      this.isInitialized = false
      console.log('数据库连接已关闭')
    }
  }
  
  /**
   * 删除数据库
   * @returns {Promise<void>}
   */
  async deleteDatabase() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.deleteDatabase(this.dbName)
      
      request.onsuccess = () => {
        this.db = null
        this.isInitialized = false
        console.log('数据库已删除')
        resolve()
      }
      
      request.onerror = () => {
        reject(new Error(`删除数据库失败: ${request.error}`))
      }
    })
  }
}
